package com.titan.core.utils.db;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;
import com.titan.core.utils.data.AssertUtils;
import com.titan.core.utils.data.StringUtils;
import com.titan.core.utils.dbinfo.dialect.DBDialect;
import com.titan.core.utils.dbinfo.dialect.IDBDialect;
import com.titan.core.utils.thread.ThreadLocalUtils;

/**
 * @author 周成功
 * @email 86898837@qq.com
 * @date 2020年02月20日
 */
public class DataSourceUtils {
    private static Map<String,DataSource> cache = new ConcurrentHashMap<String,DataSource>();
    
    
    
    public static void registerDataSource(String id, DataSource datasource) {
        if(id!=null) {
            cache.put(id, datasource);
        }
    }
    public static DataSource registerDataSource(String id, String url, int active) {
        return registerDataSource(id, null, url, null, null, active, active);
    }
    public static DataSource registerDataSource(String id, String driver, 
            String url, String username, String password, int init, int max) {
        DruidDataSource ds = new DruidDataSource();
        if(StringUtils.isNotEmpty(driver)) {
            ds.setDriverClassName(driver);
        }
        ds.setUrl(url);
        if(StringUtils.isNotEmpty(username)) {
            ds.setUsername(username);
        }
        if(StringUtils.isNotEmpty(password)) {
            ds.setPassword(password);
        }
        ds.setTestWhileIdle(false);
        ds.setInitialSize(init);  // 初始化连接数量
        ds.setMaxActive(max);   // 最大并发连接数
        ds.setMinIdle(init);    // 最小空闲连接数
        ds.setMaxWait(60000);   // 配置获取连接等待超时的时间
        
        registerDataSource(id, ds);
        return ds;
    }
    public static DataSource registerDataSource(String id, IDBDialect dialect, 
            String ip, int port, String serviceName, String username, String password, int init, int max) {
        String driver = dialect.getDriverName();
        String url = dialect.getUrl(ip, port, serviceName);
        return registerDataSource(id, driver, url, username, password, init, max);
    }
    public static DataSource registerMysqlDataSource(String id,
            String ip, int port, String serviceName, String username, String password, int init, int max) {
        return registerDataSource(id, DBDialect.MYSQL.get(), ip, port, serviceName, username, password, init, max);
    }
    public static DataSource registerMssqlDataSource(String id,
            String ip, int port, String serviceName, String username, String password, int init, int max) {
        return registerDataSource(id, DBDialect.MSSQL.get(), ip, port, serviceName, username, password, init, max);
    }
    public static DataSource registerOracleDataSource(String id,
            String ip, int port, String serviceName, String username, String password, int init, int max) {
        return registerDataSource(id, DBDialect.ORACLE.get(), ip, port, serviceName, username, password, init, max);
    }
    
    
    public static DataSource getDataSource(String id) {
        return cache.get(id);
    }    

        
    private static final String CURRENT_DATASOURCEKEY = DataSourceUtils.class.getName()+".DataSource";
    public static void setCurrentDataSource(DataSource dataSource) {
        ThreadLocalUtils.setValue(CURRENT_DATASOURCEKEY, dataSource);
    }
    public static void setCurrentDataSource(String id) {
        ThreadLocalUtils.setValue(CURRENT_DATASOURCEKEY, getDataSource(id));
    }

    public static DataSource getCurrentDataSource() {
        return (DataSource)ThreadLocalUtils.getValue(CURRENT_DATASOURCEKEY);
    }

    public static void clearCurrentDataSource() {
        ThreadLocalUtils.remove(CURRENT_DATASOURCEKEY);
    }
    
    public static void close(DataSource datasource) {
        if(datasource==null) {
            return;
        }
        if(DruidDataSource.class.isAssignableFrom(datasource.getClass())) {
            DruidDataSource ds = (DruidDataSource)datasource;
            ds.close();
            return;
        } else {
//            com.alibaba.druid.pool.DruidDataSource
        }
        AssertUtils.fail("未识别的数据源类型："+datasource.getClass());
    }    
    
}
